ShowClass.java
package reflection;
import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
import java.lang.reflect.Executable;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.Arrays;
import java.util.stream.Collectors;
/**
* A program that displays a class synopsis for the named class
*
* This example is from _Java Examples in a Nutshell_. (http://www.oreilly.com)
*
* This example is provided WITHOUT ANY WARRANTY either expressed or implied.
* You may study, use, modify, and distribute it for non-commercial purposes.
* For any commercial use, see http://www.davidflanagan.com/javaexamples
*
* @author David Flanagan
* @author Robert C. Duvall
*/
public class ShowClass {
/**
* Tries to create an object using both a default constructor and one that takes a String.
*/
public static void makeClass (Class<?> clazz) {
try {
// call no-arg constructor
Object o = clazz.getDeclaredConstructor().newInstance();
System.out.println("Printing: " + o);
// call constructor whose parameter matches the given class type
o = clazz.getDeclaredConstructor(String.class).newInstance("Test");
System.out.println("Printing: " + o);
}
catch (NoSuchMethodException | IllegalAccessException | InstantiationException | InvocationTargetException e) {
// FIXME: NOT ideal, but just a basic test program
e.printStackTrace();
}
}
/**
* Display modifiers, name, superclass and interfaces of a class or interface.
* Then list all constructors, fields, and methods.
*/
public static void printClass (Class<?> c) {
// print any annotations before class
printAnnotations(c.getAnnotations(), "\n");
// print modifiers, type (class or interface), name and superclass
System.out.print(Modifier.toString(c.getModifiers()) +
// modifiers will include the "interface" keyword here...
(c.isInterface() ? " " : " class ") +
c.getName());
if (c.getSuperclass() != null) {
System.out.print(" extends " + c.getSuperclass().getName());
}
// print interfaces or super-interfaces of the class or interface.
Class<?>[] interfaces = c.getInterfaces();
if (interfaces.length > 0) {
System.out.println(c.isInterface() ? " extends " : " implements ");
printTypes(interfaces);
}
// begin class member listing
System.out.println(" {");
System.out.println(" // Constructors");
for (Constructor<?> constructor : c.getDeclaredConstructors()) {
printMethodOrConstructor(constructor);
}
System.out.println(" // Fields");
for (Field field : c.getDeclaredFields()) {
printField(field);
}
System.out.println(" // Methods");
for (Method method : c.getDeclaredMethods()) {
printMethodOrConstructor(method);
}
System.out.println("}");
}
// Print the modifiers, type, and name of a field
private static void printField (Field f) {
// print indentation
System.out.print(" ");
// print any annotations
printAnnotations(f.getAnnotations(), " ");
// print any modifiers, type, and name
System.out.println(modifiers(f.getModifiers()) + typename(f.getType()) + " " + f.getName() + ";");
}
// Print method or constructor modifiers: return type, name, parameter types, and exceptions.
private static void printMethodOrConstructor (Executable member) {
// print indentation
System.out.print(" ");
// print any annotations
printAnnotations(member.getAnnotations(), " ");
// print any modifiers
System.out.print(modifiers(member.getModifiers()));
// print return type if present
if (member instanceof Method m) {
System.out.print(typename(m.getReturnType()) + " ");
}
// print name
System.out.print(member.getName() + "(");
// print any parameters
printTypes(member.getParameterTypes());
System.out.print(")");
// print any exceptions thrown
Class<?>[] exceptions = member.getExceptionTypes();
if (exceptions.length > 0) {
System.out.print(" throws ");
}
printTypes(exceptions);
System.out.println(";");
}
// Print a list of types
private static void printAnnotations (Annotation[] annotations, String delimiter) {
for (Annotation a : annotations) {
System.out.print(a + delimiter);
}
}
// Print a list of types
private static void printTypes (Class<?>[] types) {
// preferred way as of Java 8
System.out.print(Arrays.stream(types)
.map(ShowClass::typename)
.collect(Collectors.joining(", ")));
// OLD:
//for (int k = 0; k < types.length; k += 1) {
// if (k > 0) {
// System.out.print(", ");
// }
// System.out.print(typename(types[k]));
//}
}
// Return name of an interface or primitive type, handling arrays.
private static String typename (Class<?> t) {
StringBuilder brackets = new StringBuilder();
while (t.isArray()) {
brackets.append("[]");
t = t.getComponentType();
}
return t.getName() + brackets;
}
// Return a string version of modifiers, handling spaces nicely.
private static String modifiers (int m) {
return (m == 0) ? "" : Modifier.toString(m) + " ";
}
// Simple example to show how to use this class
public static void main (String[] args) throws ClassNotFoundException {
Class<?> clazz = Class.forName((args.length > 0) ? args[0] : "java.lang.String");
printClass(clazz);
makeClass(clazz);
}
}